// 角色选择器
<template>
  <div class="chooser_container">
    <Button icon="plus" @click="handleAdd" class="c_c_button">角色选择</Button>
    <p style="padding: 0; margin: 0">
      <span v-for="item in selectedData" :key="item.id" class="selectItem"
        >{{ item.name
        }}<span @click="deleteForSelectedData(item)">x</span></span
      >
    </p>
    <a-modal
      title="角色选择"
      v-model="visible"
      @ok="handleOk"
      @cancel="handleCancel"
      :width="600"
      okText="确认"
      cancelText="取消"
    >
      <div class="c_modal_content">
        <div class="c_modal_all">
          <Tree
            v-model="checkedKeys"
            :selectable="false"
            checkable
            :tree-data="treeData"
          />
        </div>
        <div class="c_modal_selected">
          <p v-for="item in selected" :key="item.id">
            {{ item.name }}
            <Button size="small" type="link" @click="deleteSelected(item)"
              >删除</Button
            >
          </p>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script>
import Button from "ant-design-vue/lib/button/button";
import Tree from "ant-design-vue/lib/tree";

import axios from "axios";

export default {
  props: {
    requestConfig: {
      type: Object,
    },
    propsSelected: Array, //[{name:'',id:''}]
  },

  components: {
    Button,
    Tree,
  },

  watch: {
    checkedKeys(val) {
      console.log(val);
    },
    visible(val) {
      if (!!val) {
        this.checkedKeys = this.getAllKeyBySelectedKeys(
          this.treeData,
          this.selectedData
        );
      }
    },
  },
  computed: {
    // 右侧展示数据-已选择的人
    selected() {
      let selectedEndNode = this.checkedKeys.filter(
        (e) => e.indexOf("-hasChild") === -1
      );
      return selectedEndNode.map((e) => {
        let path = e.split("-");
        let obj = this.treeData;
        for (let v of path) {
          obj = obj[v].children ? obj[v].children : obj[v];
        }
        return {
          name: obj.title,
          id: obj.id,
          key: obj.key,
        };
      });
    },
  },
  data() {
    return {
      visible: false,
      selectedData: [],
      autoExpandParent: true,
      checkedKeys: [],
      // treeData: this.addKeyForData(treeData),
      treeData: [],
    };
  },

  mounted() {
    // 获取可选的角色
    let url = this.requestConfig.getRoleUrl;
    url &&
      axios
        .get(url, {
          headers: {
            [this.requestConfig.tokenField]: this.requestConfig.token,
          },
        })
        .then(
          (res) => {
            let result = res.data;
            if (result.code === 200 && result.success) {
              let data = result.data.map((e) => ({
                id: e.roleCode,
                name: e.roleName,
                title: e.roleName,
              }));
              let treeData = this.addKeyForData(data);
              this.treeData = treeData;

              this.handlePropsData(treeData); //处理props传入的数据
              console.log("treeData=>", this.treeData);
            }
          },
          (err) => {
            console.log("err", err);
          }
        );
  },

  methods: {
    handlePropsData(treeData) {
      let propsSelectedData = this.propsSelected;
      function findById(data = treeData, id) {
        for (let v of data) {
          if (v.id === id) {
            return v;
          }
          if (v.children) {
            let find = findById(v.children, id);
            if (find) {
              return find;
            }
          }
        }
      }
      let selectedD = propsSelectedData.map((e) => {
        let find = findById(treeData, e.id);
        return { id: find.id, key: find.key, name: find.name };
      });
      this.selectedData = [...selectedD];
    },
    getSelectedData() {
      return JSON.parse(
        JSON.stringify(
          this.selectedData.map((e) => ({ name: e.name, id: e.id }))
        )
      );
    },
    handleAdd() {
      this.visible = true;
    },
    getParentKey(key) {
      let keyArr = key.split("-");
      if (keyArr && keyArr.length > 1) {
        return keyArr.slice(0, -1).join("-") + "-hasChild";
      }
      return null;
    },
    deleteSelected(item) {
      let { key } = item;
      let checkedKeys = [...this.checkedKeys];

      let parentKey = this.getParentKey(key);
      if (parentKey) {
        checkedKeys = checkedKeys.filter((e) => e !== parentKey);
      }
      this.checkedKeys = checkedKeys.filter((e) => e !== key);
    },

    deleteForSelectedData(item) {
      this.deleteSelected(item);
      let { key } = item;
      let selectedData = [...this.selectedData];
      this.selectedData = selectedData.filter((e) => e.key !== key);
    },
    handleOk() {
      let selectedEndNode = this.checkedKeys.filter(
        (e) => e.indexOf("-hasChild") === -1
      );
      this.selectedData = selectedEndNode.map((e) => {
        let path = e.split("-");
        let obj = this.treeData;
        for (let v of path) {
          obj = obj[v].children ? obj[v].children : obj[v];
        }
        return {
          name: obj.title,
          id: obj.id,
          key: obj.key,
        };
      });
      this.visible = false;
    },
    handleCancel() {
      this.visible = false;
    },
    addKeyForData(data, parentKey) {
      for (let i = 0, len = data.length; i < len; i++) {
        let key = parentKey ? `${parentKey}-${i}` : i + "";
        data[i].key = key;
        if (data[i].children) {
          data[i].key = key + "-hasChild";
          this.addKeyForData(data[i].children, key);
        }
      }
      return data;
    },

    getAllKeyBySelectedKeys(treeData, selectedData) {
      let keys = selectedData.map((e) => e.key);
      function addKey(arr, parentKey) {
        let addParentKey = true;
        for (let v of arr) {
          if (v.children && v.children.length > 0) {
            addKey(v.children, v.key);
          }
          if (keys.indexOf(v.key) === -1) {
            addParentKey = false;
          }
        }
        addParentKey && parentKey && keys.push(parentKey);
      }
      addKey(treeData);
      return keys;
    },
  },
};
</script>

<style scoped>
.chooser_container {
  display: flex;
  flex-direction: column;
  padding-bottom: 10px;
}

.c_c_button {
  width: 120px;
}

.selectItem {
  display: inline-block;
  flex-direction: row;
  align-items: center;
  margin-right: 5px;
  margin-top: 5px;
  padding: 0 3px;
  padding-right: 0px;
  background-color: #eee;
  border-radius: 4px;
}

.selectItem span {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  margin-left: 5px;
  height: 15px;
  width: 15px;
  font-size: 15px;
  cursor: pointer;
  user-select: none;
  font-weight: 500;
  border-radius: 50%;

  /* background-color: red; */
}
.selectItem span:hover {
  /* font-size: 20px; */
  color: blue;
}

.c_modal_content {
  display: flex;
  flex-direction: row;
}

.c_modal_content > div {
  border: 1px solid #ddd;
  padding: 10px;
  height: calc(100vh - 400px);
  overflow-y: scroll;
}

.c_modal_content > div::-webkit-scrollbar {
  width: 5px;
}
.c_modal_content > div::-webkit-scrollbar-thumb {
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
  background: #fff;
}

.c_modal_all {
  flex: 1;
  /* background-color: red; */
  margin-right: 10px;
}

.c_modal_content .c_modal_selected {
  padding: 5px 0 0 5px;
  flex: 1;
}

.c_modal_selected p {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  /* background-color: #ddd; */
  padding: 5px 10px;
  margin: 0;
}

.c_modal_selected p:hover {
  background-color: #eee;
}
</style>